<template>
  <div>
    <el-input
        placeholder="部门名称进行搜索"
        v-model="filterText"
        prefix-icon="el-icon-search">

    </el-input>

    <el-tree
        class="filter-tree"
        :data="deps"
        :props="defaultProps"
        :filter-node-method="filterNode"
        :expand-on-click-node="false"
        ref="tree"
        style="width: 500px">
      <!-- 做了  -->
       <span class="custom-tree-node" slot-scope="{ node, data }">
        <span>{{ data.name }}</span>
        <span>
          <el-button
              class="btn"
              type="primary"
              size="mini"
              @click="() => append(data)">
            添加
          </el-button>
          <el-button
              class="btn"
              type="danger"
              size="mini"
              @click="() => remove(node, data)">
            删除
          </el-button>
        </span>
      </span>
    </el-tree>
    <!-- 展示提示弹窗 -->
    <el-dialog
        title="添加部门"
        :visible.sync="dialogVisible"
        width="30%"
        :before-close="handleClose">
      <div>
        <table>
          <tr>
            <td><el-tag>上级部门</el-tag></td>
            <td>{{pname}}</td>
          </tr>
          <tr>
            <td>
              <el-tag>部门名称</el-tag>
            </td>
            <td>
              <el-input v-model="dep.name" placeholder="请输入部门名称"></el-input>
            </td>
          </tr>
        </table>
      </div>
      <span slot="footer" class="dialog-footer">
        <el-button @click="dialogVisible = false">取 消</el-button>
        <el-button type="primary" @click="doAddDep">确 定</el-button>
      </span>
    </el-dialog>
  </div>
</template>

<script>
export default {
name: "DepMann",
  //监听filterText
  watch: {
    filterText(val) {
      this.$refs.tree.filter(val);
    }
  },
  mounted() {
    this.initDept();
  },

  data() {
    return {
      filterText: '',
      deps: [],//树结构中的数组
      defaultProps: {
        children: 'children',
        label: 'name',
      },
      dialogVisible: false,
      //添加对象
      dep:{
        name:"",
        parentId: -1,//父级ID【默认的话-1】
      },
      pname: ""//父级名称
    };
  },
  methods: {
    initDep(){
      this.dep = {
        name: "",
        parentId: ""
      }
      this.pname = ""
    },

    /**
     * 发送Ajax请求
     * */
    doAddDep(){
      if(this.dep.name){
        this.postRequest("/system/basic/department/",this.dep).then(resp => {
          if(resp){
            this.addDep2Deps(this.deps,resp.obj);
            this.dialogVisible = false;
            //初始化数据dep数据，避免出现页面的脏数据
            this.initDep();
          }
        })
      } else {
        this.$message.error("请输入要添加的部门名称")
      }
    },

    /**
     * 关闭之前的操作放法
     * */
    handleClose(){
      this.dialogVisible = false;
    },

  /**
   * 展示节点添加页面
   * */
    append(data){
      this.pname = data.name;
      this.dep.parentId = data.id;
      this.dialogVisible = true;
    },

    /**
     *删除节点方法
     * */
    remove(node, data){
      if(data.parent){
        this.$message.error("父部门删除失败");
      } else {
        this.$confirm('确定删除此【'+data.name+'】部门', '提示', {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }).then(() => {
          this.deleteRequest("/system/basic/department/"+data.id).then(resp => {
            if(resp) {
              this.removeDepFromDeps(null,this.deps,data.id);
            }
          });
        }).catch(() => {
          this.$message({
            type: 'info',
            message: '已取消删除'
          });
        });
      }
    },

  /**
   * 初始化部门管理树
   * 这里注意 后台使用了SQL递归的方式进行查询
   */
    initDept(){
      this.getRequest("/system/basic/department/").then(resp => {
        if(resp){
          this.deps = resp;
        }
      })
    },

    /**
     * 搜索过滤的方法 这个方法会被调用很多次，进行筛选
     * @param value 搜索框中的值
     * @param data JSON数组中的每一项
     * @returns {boolean} 如果为true，当前data留存，
     *                    如果为false 那么去除掉当前这个data
     */
    filterNode(value, data) {
      if (!value) return true;
      return data.name.indexOf(value) !== -1;
    },

    /**
     * 动态展示添加后的数据【防止其折叠】页面效果不太好看,使用“递归”重复赋值
     * @param deps 已经在树中的数据
     * @param obj 后端添加成功后返回的数据
     */
    addDep2Deps(deps, obj) {
      for (let i = 0; i < deps.length; i++) {
        let d = deps[i];
        if(d.id == obj.parentId){
          //把添加成功的信息的数组添加到这个children数组中去 这里使用了concat方法进行合并数组
          d.children = d.children.concat(obj);
          if(d.children.length>0){
             //添加成功后
             d.parent = true;
          }
          return;
        } else {
          //递归继续执行，直到查询完当前树结构下到底有没有符合条件的
          this.addDep2Deps(d.children,obj);
        }
      }
    },

    /**
     * 和添加的方法一样，
     * @param deps
     * @param id
     */
    removeDepFromDeps(parent,deps,id) {
      for (let i = 0; i < deps.length; i++) {
        let d = deps[i];
        //找到了你需要删除的那一项，然后移除
        if(d.id == id){
          deps.splice(i,1);
          //查看级别数组中有没有元素前有没有数据
          if(deps.length == 0){
             //当前这个的树下没有数据的话，呢么就把这个树设置成false
             parent.parent = false
          }
          return;
        } else {
          console.log(d.children)
          this.removeDepFromDeps(d,d.children,id);
        }
      }
    }
  },

}
</script>
<style>
.custom-tree-node {
  flex: 1;
  display: flex;
  align-items: center;
  justify-content: space-between;
  font-size: 14px;
  padding-right: 8px;
}
.btn{
  padding: 5px;
}
</style>
